﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using ProtoImaginer;
using ProtoImaginer.ProtoPage;

namespace ProtoImaginer.ProtoControl
{
    public partial class ControlAtom : UserControl
    {
        private Models.Control entity;
        private PageView parent;

        #region constructor
        /*====================================================================
         * Binding UI to data
         *==================================================================*/

        //used by pageview to create new control
        public ControlAtom()
        {
            InitializeComponent();
        }

        //used by pageview to create new control
        public ControlAtom(PageView parent)
        {
            entity = new Models.Control(parent.GetImageId());
            entity.Control_Top_Left_Point_X_Coordinate = 133;
            entity.Control_Top_Left_Point_Y_Coordinate = 266;
            entity.Control_Width = 133;
            entity.Control_Height = 100;
            try { Models.ProtoDataContext.AddControl(entity); }
            catch { MessageBox.Show("Unable to create new control"); return; }
            InitializeComponent();
            this.parent = parent;
        }

        //used by demo page to load control
        public ControlAtom(Models.Control controlDB)
        {
            InitializeComponent();
            entity = controlDB;

            this.Width = controlDB.Control_Width;
            this.Height = controlDB.Control_Height;

            Canvas.SetLeft(this, controlDB.Control_Top_Left_Point_X_Coordinate);
            Canvas.SetTop(this, controlDB.Control_Top_Left_Point_Y_Coordinate);

            if (IsLinked()) ColorScheme("blue");
        }

        //used by pageview to load control
        public ControlAtom(PageView parent, Models.Control controlDB)
        {
            InitializeComponent();
            entity = controlDB;
            this.Width = controlDB.Control_Width;
            this.Height = controlDB.Control_Height;

            Canvas.SetLeft(this, controlDB.Control_Top_Left_Point_X_Coordinate * 3 / 4);
            Canvas.SetTop(this, controlDB.Control_Top_Left_Point_Y_Coordinate * 3 / 4);

            if (IsLinked()) ColorScheme("blue");
            this.parent = parent;
        }
        #endregion

        #region ui event ahndler
        /*====================================================================
         * Events handler
         *==================================================================*/
        private void ControlDotDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
            }
        }

        private void ControlDotDragCompleted(object sender, DragCompletedGestureEventArgs e) {

            if (!e.Handled)
            {
                e.Handled = true;

                this.CheckMinSize();
                parent.CheckRangeWithinCanvas(this);
                entity.Control_Width = (int)(this.ActualWidth * 4 / 3);
                entity.Control_Height = (int)(this.ActualHeight * 4 / 3);

                Models.ProtoDataContext.SaveControl(entity);
            }
        }

        private void ControlDotADrag(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                if ((this.Width - e.HorizontalChange >= this.MinWidth) && (this.Height - e.VerticalChange >= this.MinHeight))
                {
                    //resize 
                    this.Width = Math.Abs(this.Width - e.HorizontalChange / parent.Scale);
                    this.Height = Math.Abs(this.Height - e.VerticalChange / parent.Scale);

                    //keep control item still 
                    Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange / parent.Scale);
                    Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange / parent.Scale);
                }
            }
        }

        private void ControlDotBDrag(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                if ((this.Width + e.HorizontalChange >= this.MinWidth) && (this.Height - e.VerticalChange >= this.MinHeight))
                {
                    //resize 
                    this.Width = Math.Abs(this.Width + e.HorizontalChange / parent.Scale);
                    this.Height = Math.Abs(this.Height - e.VerticalChange / parent.Scale);

                    //keep control item still 
                    //Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange);
                    Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange / parent.Scale);
                }
            }
        }

        private void ControlDotCDrag(object sender, DragDeltaGestureEventArgs e)
        {

            if (!e.Handled)
            {
                e.Handled = true;

                if ((this.Width + e.HorizontalChange >= this.MinWidth) && (this.Height + e.VerticalChange >= this.MinHeight))
                {
                    //resize 
                    this.Width = Math.Abs(this.Width + e.HorizontalChange / parent.Scale);
                    this.Height = Math.Abs(this.Height + e.VerticalChange / parent.Scale);

                    //keep control item still 
                    //Canvas.SetLeft(this, Canvas.GetLeft(this) - e.HorizontalChange);
                    //Canvas.SetTop(this, Canvas.GetTop(this) - e.VerticalChange);
                }
            }
        }

        private void ControlDotDDrag(object sender, DragDeltaGestureEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;

                if ((this.Width - e.HorizontalChange >= this.MinWidth) && (this.Height + e.VerticalChange >= this.MinHeight))
                {
                    //resize 
                    this.Width = Math.Abs(this.Width - e.HorizontalChange / parent.Scale);
                    this.Height = Math.Abs(this.Height + e.VerticalChange / parent.Scale);

                    //keep control item still 
                    Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange / parent.Scale);
                    //Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange);
                }
            }
        }
        #endregion

        #region UI misc
        /*====================================================================
         * non Event-handler UI changes
         *==================================================================*/

        private void CheckMinSize()
        {
            if (this.Width < this.MinWidth)
                this.Width = this.MinWidth;

            if (this.Height < this.MinHeight)
                this.Height = this.MinHeight;
        }

        public void Outline(bool flag)
        {
            if (flag)
            {
                this.ControlRect.StrokeThickness = 4;
                this.ControlDotA.Visibility = Visibility.Visible;
                this.ControlDotB.Visibility = Visibility.Visible;
                this.ControlDotC.Visibility = Visibility.Visible;
                this.ControlDotD.Visibility = Visibility.Visible;
            }
            else
            {
                this.ControlRect.StrokeThickness = 0;
                this.ControlDotA.Visibility = Visibility.Collapsed;
                this.ControlDotB.Visibility = Visibility.Collapsed;
                this.ControlDotC.Visibility = Visibility.Collapsed;
                this.ControlDotD.Visibility = Visibility.Collapsed;
            }
        }

        public void ColorScheme(String arg)
        {
            switch (arg.ToLower())
            {
                case "blue":
                    ControlRect.Fill = GlobalVariables.blueLightTheme;
                    ControlRect.Stroke = GlobalVariables.blueDarkTheme;
                    ControlDotA.Background = GlobalVariables.blueDarkTheme;
                    ControlDotB.Background = GlobalVariables.blueDarkTheme;
                    ControlDotC.Background = GlobalVariables.blueDarkTheme;
                    ControlDotD.Background = GlobalVariables.blueDarkTheme;
                    break;
                case "red":
                    ControlRect.Fill = GlobalVariables.redLightTheme;
                    ControlRect.Stroke = GlobalVariables.redDarkTheme;
                    ControlDotA.Background = GlobalVariables.redDarkTheme;
                    ControlDotB.Background = GlobalVariables.redDarkTheme;
                    ControlDotC.Background = GlobalVariables.redDarkTheme;
                    ControlDotD.Background = GlobalVariables.redDarkTheme;
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region interfaces & db

        /*====================================================================
         * non Event-handler UI changes
         *==================================================================*/

        public String GetlinkToImageId()
        {
            return entity.ControlLinkToImageId;
        }

        public void SetlinkToImageId(String imageId)
        {
            entity.ControlLinkToImageId = imageId;
        }

        public void SetPosition(Double x, Double y) {
            entity.Control_Top_Left_Point_X_Coordinate = x;
            entity.Control_Top_Left_Point_Y_Coordinate = y;
            Models.ProtoDataContext.SaveControl(entity);
        }

        public void RemoveControl() {
            Models.ProtoDataContext.DeleteControl(entity);  
        }

        public Models.Control GetControl() {
            return entity;
        }

        public bool IsLinked() {
            return entity.ControlLinkToImageId != null;
        }

        #endregion
    }
}